package leetcode.hot100;

@SuppressWarnings("all")
public class _72_编辑距离 {

    // 给你两个单词 word1 和 word2，请你计算出将 word1 转换成 word2 所使用的最少操作数
    // 你可以对一个单词进行 插入/删除/替换 这三种操作
    public int minDistance(String word1, String word2) {
        if (word1 == null || word2 == null) return -1;
        char[] chars1 = word1.toCharArray();
        char[] chars2 = word2.toCharArray();
        // dp[i][j] 是word1[0,i)转换成word2[0,j)的最小操作数
        int[][] dp = new int[chars1.length + 1][chars2.length + 1];
        // 如果都是空字符串，那么不需要转换
        dp[0][0] = 0;
        // word1[0,i)转换成空字符串需要的次数=删除操作
        for (int row = 1; row < dp.length; row++) {
            dp[row][0] = row;
        }
        // word2[0,j)转换成空字符串需要的次数=删除操作
        for (int col = 1; col < dp[0].length; col++) {
            dp[0][col] = col;
        }
        // word1[0,i)转换成word2[0,j)的次数
        for (int row = 1; row < dp.length; row++) {
            for (int col = 1; col < dp[0].length; col++) {
                int top = dp[row - 1][col] + 1;     //删除word1[0,i)的最后一个字符后由word[0,i-1)转换成word2[0,j)
                int left = dp[row][col - 1] + 1;    //删除word2[0,j)的最后一个字符后由word2[0,j-1)转换成word1[0,i)
                int leftTop = dp[row - 1][col - 1]; //同时删除word1[0,i)和word2[0,j)的最后一个字符
                // 如果最后两字符串的最后一个字符不相等，那么最后一个字符要相同还得转换一次
                if (chars1[row - 1] != chars2[col - 1]) {
                    leftTop++;
                }
                // 选择三种选择中所需次数最少的
                dp[row][col] = Math.min(Math.min(top, left), leftTop);
            }
        }
        return dp[chars1.length][chars2.length];
    }
}
